package nkr1pt.popkorn.extract;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.Exception;
import java.util.HashSet;
import java.util.Set;
import nkr1pt.popkorn.download.DownloadCandidate;
import nkr1pt.popkorn.download.DownloadCandidateItem;
import nkr1pt.popkorn.download.DownloadCandidateState;
import org.apache.commons.lang.StringUtils;

/**
 * Leverages the Linux unrar (non-free) command.
 *
 * @author Kristof Vanhaeren
 */
public class LinuxUnrarCommand implements ExtractCommand {

    public Set<DownloadCandidateItem> testCRC(DownloadCandidate downloadCandidate) throws Exception {
        Set<DownloadCandidateItem> crcErrors = new HashSet<DownloadCandidateItem>();

        DownloadCandidateItem item = downloadCandidate.getItems().iterator().next();
        String password = downloadCandidate.getArchivePassword();

        Process proc = null;
        if (StringUtils.isEmpty(password)) {
            proc = Runtime.getRuntime().exec("unrar t " + item.getAbsolutePath());
        } else {
            proc = Runtime.getRuntime().exec("unrar t -p" + password + " " + item.getAbsolutePath());
        }

        InputStream inputStream = proc.getInputStream();
        InputStreamReader isr = new InputStreamReader(inputStream);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.contains("CRC failed")) {
                if (line.contains("volume")) {
                    int beginIndexName = line.indexOf("volume") + 7;
                    String name = line.substring(beginIndexName, line.length());
                    for (DownloadCandidateItem i : downloadCandidate.getItems()) {
                        if (i.getName().equals(name)) {
                            crcErrors.add(i);
                            i.setState(DownloadCandidateState.WAITING);
                        }
                    }
                } else {
                    DownloadCandidateItem i = downloadCandidate.getItems().get(downloadCandidate.getItems().size()-1);
                    crcErrors.add(i);
                    i.setState(DownloadCandidateState.WAITING);
                }
            }
        }
        br.close();

        return crcErrors;
    }

    public boolean extract(DownloadCandidate downloadCandidate) throws Exception {
        DownloadCandidateItem item = downloadCandidate.getItems().iterator().next();
        String password = downloadCandidate.getArchivePassword();

        Process proc = null;
        if (StringUtils.isEmpty(password)) {
            proc = Runtime.getRuntime().exec("unrar e " + item.getSimpleName(), null, new File(downloadCandidate.getExtractLocation()));
        } else {
            proc = Runtime.getRuntime().exec("unrar e -p" + password + " " + item.getSimpleName(), null, new File(downloadCandidate.getExtractLocation()));
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
        String errorLine = "";
        while ((errorLine = br.readLine()) != null) {
            return false;
        }

        if (proc.waitFor() == 0) {
            return true;
        }

        return false;
    }

    public String getName() {
        return "unrar (non-free version)";
    }
}
